#pragma once

class PerspectiveCamera final :
	public ICamera
{
public:
	PerspectiveCamera(float farDist, float nearDist, float fov);
	~PerspectiveCamera();

	/*-ICamera------------------------------------------------------------------*/
	virtual bool		Update() override;
	virtual bool		IsVisible(const glm::vec3& space, const float& radius) const override;
	virtual glm::vec2	GetOnScreenCoords(const glm::mat4& modelmatrix, const glm::vec3& pnt, bool* visible) const override;

	/*--------------------------------------------------------------------------*/

	const float& GetFieldOfView() const;
	void SetFieldOfView(const float& fov);

	const glm::quat& GetQuaterion() const;
	void SetQuaternion(const glm::quat& quat);

	void BindQuaternionSource(PerspectiveCamera* camera);
	void UnbindQuaternionSource();

	void SetRotation(const glm::vec3& rotation);
	void RotateX(float angInDeg);
	void RotateY(float angInDeg);
	void RotateZ(float angInDeg);
	void ZeroRotate();

	const glm::vec3& GetNEDirection() const;
	const glm::vec3& GetNWDirection() const;
	const glm::vec3& GetSEDirection() const;
	const glm::vec3& GetSWDirection() const;

private:
	/*-ICamera------------------------------------------------------------------*/
	virtual	bool		UpdateProjectionMatrix() override;
	virtual bool		UpdateViewMatrix() override;

	/*--------------------------------------------------------------------------*/

	bool UpdateFrustum();

	glm::vec3			m_NWdirection;
	glm::vec3			m_NEdirection;
	glm::vec3			m_SWdirection;
	glm::vec3			m_SEdirection;

	glm::quat			m_cameraQuat;
	float				m_fieldOfView;

	glm::vec4			m_fL;
	glm::vec4			m_fR;
	glm::vec4			m_fB;
	glm::vec4			m_fT;
	glm::vec4			m_fN;
	glm::vec4			m_fP;

	PerspectiveCamera*	m_quatSource;
};